package net;

import game.Game;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public final class Communications extends Thread{
   public static final int STARTING_PORT = 4444;
   private ServerSocket serverSocket;
   private Socket userSocket;
   private List<ClientSession> clientSessions;
   private Game game;
   
   public Communications(Game game) {
      this.game = game;
      try {
         serverSocket = new ServerSocket(STARTING_PORT);
      } catch (IOException e) {
         System.out.println("Setting up a ServerSocket on port " + STARTING_PORT + " failed.");
      }
      clientSessions = new ArrayList<ClientSession>();
      start();
   }
   
   /**
    * Sends a message to all users except the sender
    */
   public void dispatchAllUsersExcept(String msg, ClientSession sender) {
      for (ClientSession client : clientSessions) {
         if (sender != client) {
            client.dispatch(sender.getPlayer() + ": " + msg);
         }
      }
   }
   
   /**
    * Sends a server alert.
    */
   public void dispatchServerMsg(String msg) {
      msg = msg.toUpperCase();
      for (ClientSession client : clientSessions) {
         client.dispatch("[SERVER] > " + msg);
      }
   }
   
   @Override
   public void run() {
      try {
         listenConnections();
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
   
   /**
    * Listens to incoming connections
    */
   private void listenConnections() throws IOException {
      while(true) {
         userSocket = serverSocket.accept();
         ClientSession clientSession = new ClientSession(userSocket, game, this);
         addClientSession(clientSession);
         clientSession.start();
      }
   }
   
   private synchronized void addClientSession(ClientSession session) {
      clientSessions.add(session);
   }
   
   public synchronized void removeClientSession(ClientSession session) {
      clientSessions.remove(session);
   }
}
